home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 012 / atfastky.arc / ATFASTKY.ASM next >
Encoding:
Assembly Source File  |  1987-03-22  |  8.8 KB  |  242 lines

  1. page ,132
  2. title - atfastky.asm   (hardware keyboard accelerator)
  3.  
  4.  
  5. ;---------- ATFASTKY.ASM -- AT HARDWARE KEYBOARD ACCELERATOR
  6. ;
  7. ;    ATFASTKY programs the keyboard of the AT and 80386 machines via
  8. ;the 8024 keyboard controller and sets the delay and repeat rates associated
  9. ;with the key repeat function.  This program will not work with machines such
  10. ;as IBM PC's, XT's, or JR's which do not have an 8024 chip, or on machines
  11. ;whose keyboards do not support this feature.  The program is invoked
  12. ;by typing:
  13. ;
  14. ;    "ATFASTKY d r"  or simply "ATFASTKY"
  15. ;
  16. ;    In the latter case (no command line arguments), a default combination
  17. ;of d=0 r=0 is assumed (shortest delay, fastest repeat).  If you want to
  18. ;change these default values, replace the 0 values where 'delay' and 'repeat'
  19. ;are initialized (bottom of program) with the values you want.  NOTE: no
  20. ;error checking is done on the default values, so if you change them, make
  21. ;sure you replace them with valid values.
  22. ;    In the former case, 'd' is a number 0-3 which represents the delay
  23. ;factor you want (the time delay between the initial key press and the
  24. ;activation of the repeat feature), and 'r' is a number 0-31 representing the
  25. ;repeat rate you want.  NOTE THAT THE COMMAND LINE IS VERY SENSITIVE TO WHAT
  26. ;YOU TYPE. THERE MUST BE ONE AND ONLY ONE SPACE BETWEEN THE PROGRAM NAME AND
  27. ;THE DELAY VALUE, AS WELL AS ONE AND ONLY ONE SPACE BETWEEN THE DELAY VALUE
  28. ;AND THE REPEAT VALUE.  ANY OTHER VARIATION (EXCEPT FOR THE EMPTY COMMAND
  29. ;LINE) WILL RESULT IN AN ERROR MESSAGE.
  30. ;
  31. ;    The actual command byte passed to the keyboard which specifies the
  32. ;delay/repeat combination you want is delay*32 + repeat.
  33. ;
  34. ; |---------- REPEAT VALUES --------|           |---- DELAY VALUES ----|
  35. ;
  36. ;Val(r)    keys/sec    Val(r)    keys/sec    Val(d)  Time delay from 1st press
  37. ;
  38. ;0    30.0;        16    7.5        0     250ms
  39. ;1    26.6;        17    6.7        1     500ms
  40. ;2    24.0;        18    6.0        2     750ms
  41. ;3    21.8;        19    5.5        3    1000ms
  42. ;4    20.0;        20    5.0
  43. ;5    18.4;        21    4.6
  44. ;6    17.1;        22    4.3
  45. ;7    16.0;        23    4.0
  46. ;8    15.0;        24    3.7
  47. ;9    13.3;        25    3.3
  48. ;10    12.0;        26    3.0
  49. ;11    10.9;        27    2.7
  50. ;12    10.0;        28    2.5
  51. ;13     9.2;        29    2.3
  52. ;14     8.6;        30    2.1
  53. ;15     8.0;        31    2.0
  54. ;
  55. ;--------------------------------------------------------------------------------------------------
  56.  
  57. ;---- DEFINE PROGRAM CONSTANTS ---------------------------------------------------------------------
  58.  
  59. ack        EQU    0FAH        ;ACK value; acknowledgement byte returned by keyboard
  60. asciioff    EQU    030H        ;amount to subtract from ascii '0' to get numeric 0
  61. dosline        EQU    082H        ;location of command line arguments (after 1st space) in PSP
  62. doslen        EQU    080H        ;byte indicating length of command line
  63. comport8024    EQU    064H        ;port number for 8024's command/status port
  64. ioport8024    EQU    060H        ;port number for 8024's keyboard I/O port
  65. statmsk8024    EQU    002H        ;status mask to determine that 8024's buffer is empty
  66. kbd_disable    EQU    0ADH        ;8024 command to disable the keyboard
  67. kbd_enable    EQU    0AEH        ;8024 command to re-enable the keyboard
  68. kbd_chgspd    EQU    0F3H        ;Command to the keyboard: change repeat parameters
  69. doscall        EQU    021H        ;dos interrupt
  70. space        EQU    020H        ;ASCII space character
  71. return        EQU    00DH        ;ASCII carriage return character
  72.  
  73. ;---- SET UP SEGMENT ------------------------------------------------------------------------------
  74.  
  75. CSEG    SEGMENT PARA PUBLIC 'CODE'
  76.     ASSUME    CS:CSEG, DS:CSEG, ES:CSEG, SS:CSEG
  77.  
  78. ORG    100H
  79.  
  80. ;---- PROGRAM SECTION ------------------------------------------------------------------------------
  81.  
  82. atfastkey    PROC NEAR
  83.  
  84. ;Examine the command line length; if it's zero, jump directly to the speed setting routine.  In
  85. ;this case it will use the default 'repeat' and 'delay' values.
  86.  
  87. entry:        MOV    BX,0        ;clear BX
  88.         MOV    BL,doslen[BX]    ;length of program's command line
  89.         OR    BL,BL        ;make sure it has a length
  90.         JNZ    parse        ;command line given, parse it
  91.         JMP    setspeed    ;no command line given, default to fastest delay/repeat (0/0)
  92.  
  93. ;Look at the first command line argument.  Make sure it is only one byte long.
  94.  
  95. parse:        CLD            ;set direction flag for string scan
  96.         MOV    DI,dosline    ;move offset of first command line arg into DI
  97.         MOV    CX,0FFFFH    ;move a big scan count into CX
  98.         MOV    AL,space    ;character to look for (separating space between args)
  99.     REPNE    SCASB            ;scan the 1st argument for its terminating space
  100.         CMP    CX,0FFFDH    ;see if 1st arg is 1 byte long
  101.         JNE    err1        ;bad command line (improper 1st arg length)
  102.  
  103. ;Determine the numeric value of the 1st arg ASCII character.  If its not between 0 and 3
  104. ;then exit with an error message
  105.  
  106.         MOV    AL,[DI-2]    ;move 1st arg (single byte) into AX
  107.         SUB    AL,asciioff    ;convert it to a number
  108.         CMP    AL,0        ;see if its less than 0
  109.         JL    err1        ;bad 1st argument (digit is < 0)
  110.         CMP    AL,3        ;see if its greater than 3
  111.         JA    err1        ;bad 1st argument (digit is > 3)
  112.  
  113. ;First argument (delay) is valid, multiply it by 32 and save it
  114.  
  115.         MOV    BL,32
  116.         MUL    BL        ;shift 1st arg to proper position in keyboard cmd byte
  117.         MOV    delay,AL    ;good 1st argument, save it in delay
  118.  
  119. ;Look at the second command line argument, make sure it is only one or two characters long;
  120. ;if not, exit with the error message.
  121.  
  122.         MOV    AL,return    ;search for terminating carriage return; DI is already pointing
  123.     REPNE    SCASB            ;to the right place as a result of the last SCASB
  124.  
  125.         XOR    AL,AL        ;So 10's digit * 10 = 0 if there is no 10's digit
  126.         XOR    DL,DL        ;So 10's digit = 0 in 1's digit test
  127.         CMP    CX,0FFFBH    ;see if only one digit was given
  128.         JE    X1        ;single digit given, jump to X1
  129.         CMP    CX,0FFFAH    ;see if two digits were given
  130.         JNE    err1        ;bad 2nd argument (2nd argument has improper length)
  131.  
  132. ;Second argument is of proper length and involves a 10's digit.  Convert the 10's ASCII character
  133. ;into a number and make sure its valid (between 0 and 3).
  134.  
  135.         MOV    AL,[DI-3]    ;get 10's digit and convert it into a number
  136.         SUB    AL,asciioff
  137.         CMP    AL,0
  138.         JL    err1        ;bad 2nd argument (10's digit is < 0)
  139.         CMP    AL,3
  140.         JA    err1        ;bad 2nd argument (10's digit > 3)
  141.         MOV    DL,AL        ;save 10's digit in DL
  142.         MOV    BL,10
  143.         MUL    BL        ;multiply good 2nd argument 10's digit by 10
  144.  
  145. ;Evaluate second arguments 1's digit.  Convert it to a number and make sure its valid,
  146. ;i.e.  10's digit 0-2 -> 1's digit 0-9, 10'd digit 3 -> 1's digit 0-1
  147.  
  148.  
  149. X1:        MOV    BL,[DI-2]    ;get 1's digit and convert it into a number
  150.         SUB    BL,asciioff
  151.         CMP    BL,0
  152.         JL    err1        ;bad 2nd argument (1's digit is < 0)
  153.         CMP    BL,9
  154.         JA    err1        ;bad 2nd argument (1's digit is > 9)
  155.  
  156.         CMP    DL,3        ;see if 10's digit is 3
  157.         JB    calc_2nd    ;(it's 0 if we jumped to X1)
  158.         CMP    BL,2
  159.         JB    calc_2nd    ;if no jump, 2nd arg is bad (arg > 31)
  160. err1:        JMP    com_error
  161.  
  162. ;Combine the 10's digit and 1's digit to form the 'repeat' value and save it
  163.  
  164. calc_2nd:    ADD    AL,BL
  165.         MOV    repeat,AL
  166.  
  167. ;Now we're ready to talk to the keyboard.  First we must remove any stray keys
  168. ;which might be left in the 8024's buffer by flushing it.
  169.  
  170. ;---- FLUSH THE 8024's BUFFER --------------------------------------------------------
  171.  
  172. setspeed:    MOV    AH,01H        ;see if there's a keystroke waiting to be read
  173.         INT    16H
  174.         JZ    fastkey
  175.  
  176. ;read characters out of the keyboard buffer until its empty
  177.  
  178. flush:        XOR    AH,AH        ;there is; read it
  179.         INT    16H
  180.         MOV    AH,01H        ;see if there's another
  181.         INT    16H
  182.         JNZ    flush        ;loop until all characters are flushed
  183.  
  184. ;confirm that the 8042 buffer is empty
  185.  
  186. fastkey:    IN    AL,comport8024        ;read the 8042 keyboard controller
  187.         AND    AL,statmsk8024        ;wait for its input buffer to be empty
  188.         JNZ    flush            ;on the off chance the user got a
  189.                         ;keystroke in edgewise
  190.  
  191. ;---- PROGRAM THE KEYBOARD -------------------------------------------------------------
  192.  
  193. ;initialize and carry out the dialogue with the keyboard
  194.  
  195.         MOV    AL,kbd_disable        ;disable the keyboard
  196.         OUT    comport8024,AL
  197.  
  198. we1:        IN    AL,comport8024        ;wait for 8042 input buffer to empty again
  199.         AND    AL,statmsk8024
  200.         JNZ    we1    
  201.  
  202.         MOV    AL,kbd_chgspd        ;tell the keyboard you want to change the repeat rate
  203.         OUT    ioport8024,AL
  204.  
  205. wack1:        IN    AL,ioport8024        ;wait for an ack from the keyboard
  206.         CMP    AL,ack
  207.         JNE    wack1
  208.  
  209.         MOV    AL,repeat        ;calculate the speed
  210.         MOV    BL,delay
  211.         OR    AL,BL
  212.         OUT    ioport8024,AL        ;send delay/repeat byte to keyboard
  213.  
  214. wack2:        IN    AL,ioport8024        ;wait for another ack
  215.         CMP    AL,ack
  216.         JNE    wack2
  217.  
  218. we2:        IN    AL,comport8024        ;wait for an empty 8042 buffer
  219.         AND    AL,statmsk8024
  220.         JNZ    we2
  221.  
  222.         MOV    AL,kbd_enable
  223.         OUT    comport8024,AL        ;re-enable keyboard
  224.         JMP    exit
  225.  
  226. com_error:    LEA    DX,errmsg
  227.         MOV    AH,09H            ;DOS print string function
  228.         INT    doscall
  229. exit:        ret
  230.  
  231. ;---- STATIC VARIABLES --------------------------------------------------------------------------
  232.  
  233. errmsg        db    13,10
  234.         db    'ATFASTKY error - USAGE: "ATFASTKY delay repeat" (delay:0-3, repeat:0-31)'
  235.         db    13,10,'$'
  236. delay        db    0        ;store repeat value, default = 0
  237. repeat        db    0        ;store repeat value, default = 0
  238.  
  239. atfastkey    ENDP
  240. CSEG        ENDS
  241.         END    entry
  242.